package org.fuxia.im.db.dao.base;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate3.HibernateCallback;

/**
 * 所有DAO的基本接口，提供基本的增删查改功能
 *
 * @param <T> 实体类
 * @param <PK>主键类
 */
public interface GenericDAO<T, PK extends Serializable>
{

	// -------------------- 基本检索、增加、修改、删除操作 --------------------   
	/**
	 *  存储实体到数据库   
	 */
	public PK save(T entity);

	/**
	 *  存储实体到数据库   
	 */
	public void saveOrUpdate(T entity);

	/**
	 *  增加或更新集合中的全部实体   
	 */
	public void saveOrUpdateAll(Collection<T> entities);

	/**
	 *  更新实体   
	 */
	public void update(T entity);

	/**
	 *  删除指定的实体   
	 */
	public void delete(T entity);

	/**
	 *  删除集合中的全部实体   
	 */
	public void deleteAll(Collection<T> entities);

	/**
	 *  根据主键删除指定实体   
	 */
	public void deleteByPK(PK id);

	/**
	 *  根据主键获取实体。如果没有相应的实体，返回 null。   
	 */
	public T getByPK(PK id);

	/**
	*  根据主键获取实体并加锁。如果没有相应的实体，返回 null。   
	*/
	public T getByPKWithLock(PK id , LockMode lockMode);

	/**
	 *  根据主键获取实体。如果没有相应的实体，抛出异常。   
	 */
	public T loadByPK(PK id);

	/**
	 *  获取全部实体。   
	 */
	public List<T> loadAll();

	/**
	 * 获取指定范围的全部实体
	 */
	public List<T> findAll(int firstResult , int maxResults);

	public T merge(T entity);

	// -------------------- HSQL ----------------------------------------------   

	/**
	 *  使用HSQL语句直接增加、更新、删除实体   
	 */
	public int bulkUpdate(String queryString);

	/**
	 *  使用带参数的HSQL语句增加、更新、删除实体   
	 */
	public int bulkUpdate(String queryString , Object[] values);

	/**
	 *  使用HSQL语句检索数据   
	 */
	public List find(String queryString);

	/**
	 *  使用带参数的HSQL语句检索数据   
	 */
	public List find(String queryString , Object[] values);

	/**
	 *  使用带命名的参数的HSQL语句检索数据   
	 */
	public List findByNamedParam(String queryString , String[] paramNames , Object[] values);

	/**
	 *  使用命名的HSQL语句检索数据   
	 */
	public List findByNamedQuery(String queryName);

	/**
	 *  使用带参数的命名HSQL语句检索数据   
	 */
	public List findByNamedQuery(String queryName , Object[] values);

	/**
	 *  使用带命名参数的命名HSQL语句检索数据   
	 */
	public List findByNamedQueryAndNamedParam(String queryName , String[] paramNames , Object[] values);

	/**
	 *  使用HSQL语句检索数据，返回 Iterator   
	 */
	public Iterator<?> iterate(String queryString);

	/**
	 *  使用带参数HSQL语句检索数据，返回 Iterator   
	 */
	public Iterator<?> iterate(String queryString , Object[] values);

	/**
	 *  关闭检索返回的 Iterator   
	 */
	public void closeIterator(Iterator<?> it);

	// -------------------------------- Criteria ------------------------------   

	/**
	 *  创建与会话无关的检索标准对象   
	 */
	public DetachedCriteria createDetachedCriteria();

	/**
	 *  创建与会话绑定的检索标准对象   
	 */
	public Criteria createCriteria();

	/**
	 *  使用指定的检索标准检索数据   
	 */
	public List<T> findByCriteria(DetachedCriteria criteria);

	/**
	 *  使用指定的检索标准检索数据，返回部分记录   
	 */
	public List<T> findByCriteria(DetachedCriteria criteria , int firstResult , int maxResults);

	/**
	 *  使用指定的实体及属性检索（满足除主键外属性＝实体值）数据   
	 */
	public List<T> findEqualByEntity(T entity , String[] propertyNames);

	/**
	 *  使用指定的检索标准检索数据，返回指定范围的记录   
	 */
	public Integer getRowCount(DetachedCriteria criteria);

	// -------------------------------- 其他 --------------------------------   

	/**
	 *  加锁指定的实体   
	 */
	public void lock(T entity , LockMode lockMode);

	/**
	 *  强制初始化指定的实体   
	 */
	public void initialize(Object proxy);

	/**
	 *  强制立即更新缓冲数据到数据库（否则仅在事务提交时才更新）   
	 */
	public void flush();

	/**
	 * 获取当前DAO对应的实体类
	 */
	public Class<T> getEntityClass();

	public List<T> executeFind(HibernateCallback<?> hibernateCallback);
}